﻿using _404park.Core.Crawler;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace _404park.ApplicationServices.Crawler.Parser.Provider
{
    public class GoogleCSEParser : BaseFeedParser
    {
        public override string BaseUrl
		{
			get
			{
				return "https://www.googleapis.com/customsearch/v1?key=AIzaSyAN1HIf6xWu7fIGGwOuaQBf8d_UO2C6ypo&cx=partner-pub-5758834367841845:4833266854&q={0}&alt=atom&num=10&start={1}";
			}
		}

        internal override string GetFeedUrl(string keyword, int start = 0)
        {
            return string.Format(BaseUrl, keyword, start+1);
        }

        protected internal override IList<Feed> ParseFeed(string data)
        {
            var feedList = new List<Feed>();
            var xmlDoc = XDocument.Parse(data);
            var defaultNameSpace = xmlDoc.Root.GetDefaultNamespace();
            var cseNameSpace = xmlDoc.Root.GetNamespaceOfPrefix("cse");
            if (xmlDoc.Root != null)
            {
                xmlDoc.Root.Descendants(defaultNameSpace + "entry").ToList().ForEach(element => feedList.Add(CreateFeedItem(element, defaultNameSpace, cseNameSpace)));
            }
            return feedList;
        }

        private Feed CreateFeedItem(XElement xElement, XNamespace defaultNameSpace, XNamespace cseNameSpace)
        {
            var title = xElement.Element(defaultNameSpace + "title") != null ? xElement.Element(defaultNameSpace + "title").Value : string.Empty;
            var description = xElement.Element(defaultNameSpace + "summary") != null ? xElement.Element(defaultNameSpace + "summary").Value : string.Empty;
            var clickUrl = xElement.Element(defaultNameSpace + "link") != null ? xElement.Element(defaultNameSpace + "link").Attribute("href").Value : string.Empty;
            var updateDate = xElement.Element(defaultNameSpace + "updated") != null ? xElement.Element(defaultNameSpace + "updated").Value : string.Empty;
            var displayUrl = GetDisplayUrl(xElement, cseNameSpace);

            var feed = new Feed
            {
                Title = title,
                Description = description,
                ClickUrl = clickUrl,
                DisplayUrl = displayUrl,
                UpdateDate = updateDate
            };
            return feed;
        }

        private string GetDisplayUrl(XElement xElement, XNamespace cseNameSpace)
        {
            var pageMapElement = xElement.Element(cseNameSpace + "PageMap");
            if (pageMapElement == null) return null;

            var dataImageObjectElement = pageMapElement.Elements(cseNameSpace + "DataObject").Where(x =>
            {
                if (x.Attribute("type") == null) return false;
                if (x.Attribute("type").Value.Equals("cse_thumbnail", StringComparison.InvariantCultureIgnoreCase)) return true;
                return false;
            }).FirstOrDefault();
            if (dataImageObjectElement == null) return null;

            var imageElement = dataImageObjectElement.Elements(cseNameSpace + "Attribute").Where(x => {
                if (x.Attribute("name") == null) return false;
                if (x.Attribute("name").Value.Equals("src", StringComparison.InvariantCultureIgnoreCase))
                    return true;
                return false;
            }).FirstOrDefault();
            if (imageElement == null) return null;

            if (imageElement.Attribute("value") != null)
                return imageElement.Attribute("value").Value;

            return null;
        }
    }
}
